#include "Base.h"
#include "ProductList.h"
#include "Log.h"

int compProductInfo(const void *pElement1,const void *pElement2)
{
	ProductInfo *pProduct1 = *(ProductInfo **)pElement1;
	ProductInfo *pProduct2 = *(ProductInfo **)pElement2;
	return pProduct1->m_dwProductId - pProduct2->m_dwProductId;
}

CProductList::CProductList(void)
{
	m_tmLastSynTime = 0;
	m_dwGameId = 0;
}

CProductList::~CProductList(void)
{
}

void CProductList::AddProductInfo(MLAddProductMsg *pMsg, CMatchPlayer *pMatchPlayer)
{
	m_lockProductList.Lock();
	ProductInfo productInfo;
	productInfo.m_dwProductId = pMsg->m_dwProductId;
	ProductInfo *pProductInfo = m_listProduct.Find(&productInfo, compProductInfo);
	if(pProductInfo == NULL)
	{
		pProductInfo = new ProductInfo;
		pProductInfo->m_dwProductId = pMsg->m_dwProductId;
		m_listProduct.Insert(pProductInfo, compProductInfo);
	}
	pProductInfo->m_nProductType = pMsg->m_nProductType;
	pProductInfo->m_dwGameId = pMsg->m_dwGameId;
	pProductInfo->m_tmMatchStartTime = pMsg->m_tmMatchStartTime;
	pProductInfo->m_nUnitType = pMsg->m_nUnitType;
	pProductInfo->m_dwMisIP = pMsg->m_dwMisIP;
	pProductInfo->m_nMisPort = pMsg->m_nMisPort;
	pProductInfo->m_stSignCost = pMsg->m_stSignCost;
	pProductInfo->m_tmCreateTime = time(NULL);
	pProductInfo->m_tmLastUpdateTime = pProductInfo->m_tmCreateTime;
	pProductInfo->m_nSignupPlayerCount = pMsg->m_nSignupPlayerCount;
	pProductInfo->m_pMatchPlayer = pMatchPlayer;
	m_lockProductList.Unlock();
}

void CProductList::UpdateProductInfo(MLUpdateProductMsg *pMsg)
{
	m_lockProductList.Lock();
	ProductInfo productInfo;
	productInfo.m_dwProductId = pMsg->m_dwProductId;
	ProductInfo *pProductInfo = m_listProduct.Find(&productInfo, compProductInfo);
	if(pProductInfo != NULL)
	{
		pProductInfo->m_nSignupPlayerCount = pMsg->m_nSignupPlayer;
		pProductInfo->m_tmMatchStartTime = pMsg->m_tmMatchStartTime;
		pProductInfo->m_nStatus = pMsg->m_nStatus;
		pProductInfo->m_tmLastUpdateTime = time(NULL);
	}

	m_lockProductList.Unlock();
}

void CProductList::DelProductInfo(MLDelProductMsg *pMsg)
{
	m_lockProductList.Lock();
	ProductInfo productInfo;
	productInfo.m_dwProductId = pMsg->m_dwProductId;
	int nPos = m_listProduct.FindPos(&productInfo, compProductInfo);
	if(nPos >= 0)
	{
		ProductInfo *pProductInfo = m_listProduct.GetAt(nPos);
		m_listProduct.RemoveAt(nPos);
		delete pProductInfo;
	}
	m_lockProductList.Unlock();
}

ProductInfo *CProductList::FindProductInfo(DWORD dwProductId)
{
	m_lockProductList.Lock();
	ProductInfo productInfo;
	productInfo.m_dwProductId = dwProductId;
	ProductInfo *pProductInfo = m_listProduct.Find(&productInfo, compProductInfo);
	m_lockProductList.Unlock();
	return pProductInfo;
}

void CProductList::DeleteByMatchPlayer(CMatchPlayer *pMatchPlayer)
{
    m_lockProductList.Lock();
	int nCount = m_listProduct.GetCount();
	for(int i = nCount - 1; i >= 0; i--)
	{
        ProductInfo *pProductInfo = m_listProduct.GetAt(i);
		if(pProductInfo->m_pMatchPlayer == pMatchPlayer)
		{
            m_listProduct.RemoveAt(i);
			delete pProductInfo;
		}
	}
	m_lockProductList.Unlock();
}

void CProductList::SynProductListMsg()
{
	m_lockProductList.Lock();
	m_lockSynMsg.Lock();

	m_synProductListMsg.m_listProductInfo.DeleteAll();
	int nCount = m_listProduct.GetCount();
	for(int i = 0; i < nCount; i++)
	{
		ProductInfo *pProductInfo = m_listProduct.GetAt(i);
		if(pProductInfo->m_tmLastUpdateTime >= m_tmLastSynTime)
		{
			ProductInfo *pSynProductInf = new ProductInfo(*pProductInfo);
			m_synProductListMsg.m_listProductInfo.AddTail(pSynProductInf);
		}
	}
	m_tmLastSynTime = time(NULL);
	//WriteLog("SynProductListMsg Update Product Count = %d", nCount);
	m_lockSynMsg.Unlock();
	m_lockProductList.Unlock();
}

void CProductList::Lock()
{
    m_lockProductList.Lock();
}

void CProductList::Unlock()
{
    m_lockProductList.Unlock();
}

void CProductList::LockSynMsg()
{
    m_lockSynMsg.Lock();
}

void CProductList::UnlockSynMsg()
{
    m_lockSynMsg.Unlock();
}